﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RM.Core
{
    /// <summary>
    /// Configures the inversion of control container with services used by RM.
    /// </summary>
    public class ContainerConfigurer
    {
        public virtual void Configure(IEngine engine, ContainerManager containerManager, RmConfig configuration)
        {
            //other dependencies
            containerManager.AddComponentInstance<RmConfig>(configuration, "RM.configuration");
            containerManager.AddComponentInstance<IEngine>(engine, "RM.engine");
            containerManager.AddComponentInstance<ContainerConfigurer>(this, "RM.containerConfigurer");
            //type finder
            containerManager.AddComponent<ITypeFinder, WebAppTypeFinder>("RM.typeFinder");
            //register dependencies provided by other assemblies
            var typeFinder = containerManager.Resolve <ITypeFinder>();
            containerManager.UpdateContainer(x =>
                {
                    var drTypes = typeFinder.FindClassesOfType<IDependencyRegistrar>();
                    var drInstances = new List<IDependencyRegistrar>();
                    foreach (var drType in drTypes)
                        drInstances.Add((IDependencyRegistrar)Activator.CreateInstance(drType));
                    //sort
                    drInstances = drInstances.AsQueryable().OrderBy(t => t.Order).ToList();
                    foreach (var dependencyRegistrar in drInstances)
                        dependencyRegistrar.Register(x, typeFinder);
                }
                );
        }
    }
}
